package com.xiao.androidcompose01.api

import androidx.annotation.Keep
import com.xiao.androidcompose01.api.data.AccountData
import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.KSerializer
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import kotlinx.serialization.descriptors.SerialDescriptor
import kotlinx.serialization.descriptors.buildClassSerialDescriptor
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder
import kotlinx.serialization.json.Json
import kotlinx.serialization.json.JsonDecoder
import kotlinx.serialization.json.JsonEncoder
import kotlinx.serialization.json.JsonPrimitive
import kotlinx.serialization.json.buildJsonObject
import kotlinx.serialization.json.contentOrNull
import kotlinx.serialization.json.encodeToJsonElement
import kotlinx.serialization.json.intOrNull
import kotlinx.serialization.json.jsonObject
import kotlinx.serialization.json.jsonPrimitive

@Serializable(with = NullEmptyObjectSerializer::class)
@Keep
data class NetResponse<T>(
   @SerialName("code")
   val code:Int,
   @SerialName("msg")
   val msg:String,
    @SerialName("data")
   val data:T?
){
   fun requestData():T{
      if (data!=null && code < 100){
         return data
      }
      throw IllegalArgumentException(msg)
   }
   
   fun requestDataNull():T?{
      if (data!=null && code<100){
         return data
      }
      return null
   }
}

object NullEmptyObjectSerializer : KSerializer<NetResponse<AccountData>>{
   override val descriptor: SerialDescriptor
      get() = buildClassSerialDescriptor("NullEmptyObjectSerializer")
   
   
   @OptIn(ExperimentalSerializationApi::class)
   override fun serialize(encoder: Encoder, value: NetResponse<AccountData>) {
      val jsonEncoder = encoder as? JsonEncoder
      if (value.data==null){
         val json = buildJsonObject {
            put("code",JsonPrimitive(value.code))
            put("msg",JsonPrimitive(value.msg))
         }
         jsonEncoder?.encodeJsonElement(json)
      }else{
         jsonEncoder?.encodeJsonElement(Json.encodeToJsonElement(value))
      }
   }
   
   override fun deserialize(decoder: Decoder): NetResponse<AccountData> {
      val jsonDecoder = decoder as? JsonDecoder
      val jsonElement = jsonDecoder?.decodeJsonElement()
      if (jsonElement!=null){
         val json = jsonElement.jsonObject
         val code = json["code"]?.jsonPrimitive?.intOrNull
         val msg = json["msg"]?.jsonPrimitive?.contentOrNull
         val data = json["data"]?.jsonObject
         if (data == null || data.isEmpty()){
            return NetResponse(code?:0,msg?:"",null)
         }else{
            val d = Json.decodeFromJsonElement(AccountData.serializer(),data)
            return NetResponse(code?:0,msg?:"",d)
         }
      }
      return NetResponse(0,"",null)
   }
   
}